package simulator.jsoncode;

import simulator.enums.Direction;
import simulator.enums.LaneType;
import simulator.enums.LightState;
import simulator.types.Lane;
import net.minidev.json.JSONArray;
import net.minidev.json.JSONObject;

public class JSONDecoder
{
	public static final String TLU_LANE_FIELD = "light";
	public static final String TLU_STATE_FIELD = "state";
	
	
	private JSONDecoder()
	{
		//pure static class
	}
	
	public static void decodeJSON(Object root, DecodeCallback callback)
	{
		if(root instanceof JSONObject)
		{
			decodeObject((JSONObject) root, callback);
		}
		else if(root instanceof JSONArray)
		{
			decodeArray((JSONArray) root, callback);
		}
		else
		{
			System.err.println("Error: decodeJSON called with non-JSON object: " + root.toString());
		}
	}
	
	private static void decodeObject(JSONObject obj, DecodeCallback callback)
	{
		//determine object type
		//only know one for now
		
		if(isTLU(obj))
			decodeTLU(obj, callback);
		
		else
			System.err.println("Error: decodeJSON did not recognize current JSONObject type: " + obj.toJSONString());
	}
	
	private static void decodeArray(JSONArray arr, DecodeCallback callback)
	{
		int numElements = arr.size();
		
		for(int i=0; i<numElements; i++)
		{
			decodeJSON(arr.get(i), callback);
		}
	}
	
	private static boolean isTLU(JSONObject obj)
	{
		return obj.containsKey(TLU_LANE_FIELD) && obj.containsKey(TLU_STATE_FIELD);
	}
	
	private static void decodeTLU(JSONObject obj, DecodeCallback callback)
	{
		Lane which;
		LightState state;
		
		Object which_data = obj.get(TLU_LANE_FIELD);
		Object state_data = obj.get(TLU_STATE_FIELD);
		
		if(which_data instanceof String && state_data instanceof String)
		{
			String whichStr = (String) which_data;
			String stateStr = (String) state_data;
			
			if(stateStr.length() < 2)
			{
				System.err.println("Error: decodeJSON: illegal data in TLU JSON object: " + obj.toJSONString());
				return;
			}
			
			Direction d = Direction.getFromChar(whichStr.charAt(0));
			LaneType t = LaneType.fromID(Integer.valueOf(whichStr.substring(1)));
			state = LightState.fromString(stateStr);
			
			if(d == null || t == null || state == null)
			{
				System.err.println("Error: decodeJSON: illegal data in TLU JSON object: " + obj.toJSONString());
				return;
			}
			
			which = new Lane(d, t);
			
			callback.trafficLightUpdate(which, state);
		}
		else
		{
			System.err.println("Error: decodeJSON: unrecognized data in TLU JSON object: " + obj.toJSONString());
		}
	}
}
